package com.open.annotation.aspect;

import com.google.common.util.concurrent.RateLimiter;
import com.open.annotation.Limit;
import com.open.exception.WebException;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;

import java.util.concurrent.ConcurrentHashMap;

/**
 * @author tanyongpeng
 * <p>des</p>
 **/
public class LimitAspect {

    private static final ConcurrentHashMap<String, RateLimiter> map = new ConcurrentHashMap<>();

    @Pointcut("@annotation(com.open.annotation.Limit)")
    public void cut(){}


    @Around("cut()")
    public Object deal(ProceedingJoinPoint point) throws Throwable {
        final MethodSignature signature = (MethodSignature) point.getSignature();
        final Limit limit = signature.getMethod().getAnnotation(Limit.class);
        final int value = limit.limit();
        final String name = signature.getMethod().toString();
        RateLimiter rateLimiter;
        if(map.containsKey(name)){
            rateLimiter = map.get(name);
        }else{
            rateLimiter = RateLimiter.create(value);
            map.put(name, rateLimiter);
        }
        if(rateLimiter.tryAcquire()){
            return point.proceed();
        }else{
            throw new WebException("当前网站太火爆，人太拥挤，请稍后再试");
        }
    }
}
